package com.lanyou.esb.redis.proxy.base;

import java.io.IOException;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.lanyou.esb.redis.JedisPoolUtils;
import com.lanyou.esb.redis.proxy.ListJedisProxy;

/**
 * List数据类型,操作Redis基础代理类
 * 
 * @author Davey.wu
 */
public abstract class BaseListJedisProxy<T> extends BaseJedisProxy<T> implements
		ListJedisProxy<T> {
	private String listKey;

	public void setListKey(String listKey) {
		this.listKey = listKey;
	}

	@Override
	public String getListKey() {
		return listKey;
	}

	@Override
	public String generateKeyFromObject(T t) {
		return getListKey();
	}

	@Override
	public void rpush(List<T> list) throws JsonProcessingException {
		if (list == null || list.isEmpty()) {
			return;
		}
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			Pipeline p = jedis.pipelined();
			for (T t : list) {
				p.rpush(this.getListKey(), this.toJson(t));
			}
			p.sync();
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	@Override
	public void lpush(String key, T t) throws JsonProcessingException {
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			jedis.lpush(key, this.toJson(t));
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	@Override
	public void lpush(Jedis jedis, String key, T t)
			throws JsonProcessingException {
		// add to redis
		jedis.lpush(key, this.toJson(t));
	}

	@Override
	public void rpush(String key, T t) throws JsonProcessingException {
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			jedis.rpush(key, this.toJson(t));
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	@Override
	public T lpop(String key) throws JsonParseException, JsonMappingException,
			IOException {
		T result = null;
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return null;
		}
		boolean broken = false;
		try {
			result = listLeftPop(jedis, key);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		return result;
	}

	@Override
	public T lpop(Jedis jedis, String key) throws JsonParseException,
			JsonMappingException, IOException {
		// TODO Auto-generated method stub
		return listLeftPop(jedis, key);
	}

	@Override
	public T rpop(String key) throws JsonParseException, JsonMappingException,
			IOException {
		T result = null;
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return null;
		}
		boolean broken = false;
		try {
			result = listRightPop(jedis, key);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		return result;
	}

	@Override
	public T rpop(Jedis jedis, String key) throws JsonParseException,
			JsonMappingException, IOException {
		// TODO Auto-generated method stub
		return listRightPop(jedis, key);
	}

	/**
	 * 从链表左侧取出一个元素
	 * 
	 * @param jedis
	 * @param key
	 * @return
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	private T listLeftPop(Jedis jedis, String key) throws JsonParseException,
			JsonMappingException, IOException {
		T target = null;
		// 从左边获取一个元素
		String value = jedis.lpop(key);
		// 将JSON字符串转换成JAVA对象
		if (target == null && StringUtils.isNotBlank(value)) {
			target = fromJson(value);
		}
		return target;
	}

	/**
	 * 从链表右侧取出一个元素
	 * 
	 * @param jedis
	 * @param key
	 * @return
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	private T listRightPop(Jedis jedis, String key) throws JsonParseException,
			JsonMappingException, IOException {
		T target = null;
		String value = jedis.rpop(this.getListKey());
		// 将JSON字符串转换成JAVA对象
		if (target == null && StringUtils.isNotBlank(value)) {
			target = fromJson(value);
		}
		return target;
	}
}
